﻿using demo.Interfaces;
using demo.Models.DTOs;
using demo.Models;
using Microsoft.EntityFrameworkCore;
using System.Linq;

namespace demo.Services
{
    public class StockService : IStockService
    {
        private readonly IRepository<StockInOrder> _stockInOrderRepository;
        private readonly IRepository<StockOutOrder> _stockOutOrderRepository;
        private readonly IRepository<StockInDetail> _stockInDetailRepository;
        private readonly IRepository<StockOutDetail> _stockOutDetailRepository;
        private readonly IRepository<Product> _productRepository;
        private readonly IRepository<Warehouse> _warehouseRepository;

        public StockService(
            IRepository<StockInOrder> stockInOrderRepository,
            IRepository<StockOutOrder> stockOutOrderRepository,
            IRepository<StockInDetail> stockInDetailRepository,
            IRepository<StockOutDetail> stockOutDetailRepository,
            IRepository<Product> productRepository,
            IRepository<Warehouse> warehouseRepository)
        {
            _stockInOrderRepository = stockInOrderRepository;
            _stockOutOrderRepository = stockOutOrderRepository;
            _stockInDetailRepository = stockInDetailRepository;
            _stockOutDetailRepository = stockOutDetailRepository;
            _productRepository = productRepository;
            _warehouseRepository = warehouseRepository;
        }
        public async Task<int> GetAllStockinsCountAsync()
        {
            return await _stockInDetailRepository.GetAllCountAsync();
        }
        public async Task<int> GetAllStockoutsCountAsync()
        {
            return await _stockOutDetailRepository.GetAllCountAsync();
        }
        public async Task AddStockInAsync(StockInDto stockInDto)
        {
            if (stockInDto == null || stockInDto.Details == null || stockInDto.Details.Count() == 0)
            {
                throw new ArgumentException("StockInDto 或其 Details 不能为空");
            }

            // 插入订单信息
            var stockInOrder = new StockInOrder
            {
                OrderDate = stockInDto.OrderDate,
                ProcessedBy = stockInDto.ProcessedBy
            };

            await _stockInOrderRepository.AddAsync(stockInOrder);

            // 插入订单明细
            foreach (var detail in stockInDto.Details)
            {
                var stockInDetail = new StockInDetail
                {
                    OrderID = stockInOrder.OrderID, // 使用插入订单时生成的 OrderID
                    ProductID = detail.ProductID,
                    WarehouseID = detail.WarehouseID,
                    Quantity = detail.Quantity,
                    PurchasePrice = detail.PurchasePrice
                };

                await _stockInDetailRepository.AddAsync(stockInDetail);
            }
        }

        public async Task AddStockOutAsync(StockOutDto stockOutDto)
        {
            if (stockOutDto == null || stockOutDto.Details == null || stockOutDto.Details.Count == 0)
            {
                throw new ArgumentException("StockInDto 或其 Details 不能为空");
            }
            var stockOutOrder = new StockOutOrder
            {
                OrderDate = stockOutDto.OrderDate,
                ProcessedBy = stockOutDto.ProcessedBy
            };
            //自增生成库存ID
            foreach (var detail in stockOutDto.Details)
            {
                var stockOutDetail = new StockOutDetail
                {
                    OrderID = stockOutOrder.OrderID,
                    ProductID = detail.ProductID,
                    WarehouseID = detail.WarehouseID,
                    Quantity = detail.Quantity,
                    SalePrice = detail.SalePrice,
                };

            }


            await _stockOutOrderRepository.AddAsync(stockOutOrder);
        }

        public async Task<List<StockInDetailDto>> GetStockInDetailsAsync(int page, int pageSize)
        {
            // 通过多表关联获取所需的数据
            var stockInDetails = await _stockInDetailRepository
                .GetAll()
                .Join(
                    _stockInOrderRepository.GetAll(),
                    detail => detail.OrderID,             // StockInDetail 的外键 OrderID
                    order => order.OrderID,               // StockInOrder 的主键 OrderID
                    (detail, order) => new
                    {
                        detail.DetailID,
                        detail.ProductID,
                        detail.WarehouseID,
                        detail.Quantity,
                        detail.PurchasePrice,
                        OrderDate = order.OrderDate,      // 入库日期
                        ProcessedBy = order.ProcessedBy  // 入库操作人
                    }
                )
                .Join(
                    _productRepository.GetAll(),
                    detailWithOrder => detailWithOrder.ProductID, // StockInDetail 的外键 ProductID
                    product => product.ProductID,                 // Product 的主键 ProductID
                    (detailWithOrder, product) => new
                    {
                        detailWithOrder.DetailID,
                        detailWithOrder.WarehouseID,
                        detailWithOrder.Quantity,
                        detailWithOrder.PurchasePrice,
                        detailWithOrder.OrderDate,
                        detailWithOrder.ProcessedBy,
                        ProductName = product.ProductName         // 商品名字
                    }
                )
                .Join(
                    _warehouseRepository.GetAll(),
                    detailWithProduct => detailWithProduct.WarehouseID, // StockInDetail 的外键 WarehouseID
                    warehouse => warehouse.WarehouseID,                 // Warehouse 的主键 WarehouseID
                    (detailWithProduct, warehouse) => new
                    {
                        detailWithProduct.DetailID,
                        detailWithProduct.ProductName,
                        WarehouseName = warehouse.WarehouseName,        // 仓库名字
                        detailWithProduct.Quantity,
                        detailWithProduct.PurchasePrice,
                        detailWithProduct.OrderDate,
                        detailWithProduct.ProcessedBy
                    }
                )
                .OrderByDescending(x => x.OrderDate)                  // 按入库日期降序排序
                .Skip((page - 1) * pageSize)                          // 分页
                .Take(pageSize)                                       // 分页大小
                .Select(x => new StockInDetailDto
                {
                    DetailID = x.DetailID,
                    ProductName = x.ProductName,
                    WarehouseName = x.WarehouseName,
                    Quantity = x.Quantity,
                    PurchasePrice = x.PurchasePrice,
                    OrderDate = x.OrderDate,
                    ProcessedBy = x.ProcessedBy
                })
                .ToListAsync();

            return stockInDetails;
        }


        public async Task<List<StockOutDetailDto>> GetStockOutDetailsAsync(int page, int pageSize)
        {
            if (page <= 0 || pageSize <= 0)
            {
                throw new ArgumentException("分页参数必须大于 0");
            }
            // 通过多表关联获取所需的数据
            var stockOutDetails = await _stockOutDetailRepository
                .GetAll()
                .Join(
                    _stockOutOrderRepository.GetAll(),
                    detail => detail.OrderID,             // StockOutDetail 的外键 OrderID
                    order => order.OrderID,               // StockOutOrder 的主键 OrderID
                    (detail, order) => new
                    {
                        detail.DetailID,
                        detail.ProductID,
                        detail.WarehouseID,
                        detail.Quantity,
                        detail.SalePrice,
                        order.OrderDate,      // 出库日期
                        order.ProcessedBy  // 出库操作人
                    }
                )
                .Join(
                    _productRepository.GetAll(),
                    detailWithOrder => detailWithOrder.ProductID, // StockOutDetail 的外键 ProductID
                    product => product.ProductID,                 // Product 的主键 ProductID
                    (detailWithOrder, product) => new
                    {
                        detailWithOrder.DetailID,
                        detailWithOrder.WarehouseID,
                        detailWithOrder.Quantity,
                        detailWithOrder.SalePrice,
                        detailWithOrder.OrderDate,
                        detailWithOrder.ProcessedBy,
                        ProductName = product.ProductName         // 商品名字
                    }
                )
                .Join(
                    _warehouseRepository.GetAll(),
                    detailWithProduct => detailWithProduct.WarehouseID, // StockOutDetail 的外键 WarehouseID
                    warehouse => warehouse.WarehouseID,                 // Warehouse 的主键 WarehouseID
                    (detailWithProduct, warehouse) => new
                    {
                        detailWithProduct.DetailID,
                        detailWithProduct.ProductName,
                        WarehouseName = warehouse.WarehouseName,        // 仓库名字
                        detailWithProduct.Quantity,
                        detailWithProduct.SalePrice,
                        detailWithProduct.OrderDate,
                        detailWithProduct.ProcessedBy
                    }
                )
                .OrderByDescending(x => x.OrderDate)                  // 按出库日期降序排序
                .Skip((page - 1) * pageSize)                          // 分页
                .Take(pageSize)                                       // 分页大小
                .Select(x => new StockOutDetailDto
                {
                    DetailID = x.DetailID,
                    ProductName = x.ProductName,
                    WarehouseName = x.WarehouseName,
                    Quantity = x.Quantity,
                    SalePrice = x.SalePrice,
                    OrderDate = x.OrderDate,
                    ProcessedBy = x.ProcessedBy
                })
                .ToListAsync();

            return stockOutDetails;
        }

        //获取给定商品指定时间段的库存记录
        public async Task<StockRecordDto> GetStockRecordsAsync(int productId, DateTime startDate, DateTime endDate)
        {
            // 查询入库记录
            var stockInRecords = await _stockInDetailRepository
                .GetAll()
                .Join(
                    _stockInOrderRepository.GetAll(),
                    detail => detail.OrderID,
                    order => order.OrderID,
                    (detail, order) => new
                    {
                        detail.DetailID,
                        detail.ProductID,
                        detail.WarehouseID,
                        detail.Quantity,
                        detail.PurchasePrice,
                        OrderDate = order.OrderDate,
                        ProcessedBy = order.ProcessedBy
                    }
                )
                .Where(record => record.ProductID == productId // 添加对 ProductID 的过滤
                                 && record.OrderDate >= startDate
                                 && record.OrderDate <= endDate) // 添加对时间范围的过滤
                .Join(
                    _warehouseRepository.GetAll(),
                    record => record.WarehouseID,
                    warehouse => warehouse.WarehouseID,
                    (record, warehouse) => new
                    {
                        record.DetailID,
                        record.ProductID,
                        record.Quantity,
                        record.PurchasePrice,
                        record.OrderDate,
                        record.ProcessedBy,
                        WarehouseName = warehouse.WarehouseName
                    }
                )
                .Join(
                    _productRepository.GetAll(),
                    record => record.ProductID,
                    product => product.ProductID,
                    (record, product) => new StockRecordDetailDto
                    {
                        RecordType = "入库",
                        Quantity = record.Quantity,
                        Price = record.PurchasePrice,
                        Date = record.OrderDate,
                        ProductName = product.ProductName,
                        WarehouseName = record.WarehouseName,
                        ProcessedBy = record.ProcessedBy
                    }
                )
                .ToListAsync();

            // 查询出库记录
            var stockOutRecords = await _stockOutDetailRepository
                .GetAll()
                .Join(
                    _stockOutOrderRepository.GetAll(),
                    detail => detail.OrderID,
                    order => order.OrderID,
                    (detail, order) => new
                    {
                        detail.DetailID,
                        detail.ProductID,
                        detail.WarehouseID,
                        detail.Quantity,
                        detail.SalePrice,
                        OrderDate = order.OrderDate,
                        ProcessedBy = order.ProcessedBy
                    }
                )
                .Where(record => record.ProductID == productId
                                 && record.OrderDate >= startDate
                                 && record.OrderDate <= endDate)
                .Join(
                    _warehouseRepository.GetAll(),
                    record => record.WarehouseID,
                    warehouse => warehouse.WarehouseID,
                    (record, warehouse) => new
                    {
                        record.DetailID,
                        record.ProductID,
                        record.Quantity,
                        record.SalePrice,
                        record.OrderDate,
                        record.ProcessedBy,
                        WarehouseName = warehouse.WarehouseName
                    }
                )
                .Join(
                    _productRepository.GetAll(),
                    record => record.ProductID,
                    product => product.ProductID,
                    (record, product) => new StockRecordDetailDto
                    {
                        RecordType = "出库",
                        Quantity = record.Quantity,
                        Price = record.SalePrice,
                        Date = record.OrderDate,
                        ProductName = product.ProductName,
                        WarehouseName = record.WarehouseName,
                        ProcessedBy = record.ProcessedBy
                    }
                )
                .ToListAsync();

            // 返回结果
            return new StockRecordDto
            {
                ProductID = productId,
                StartDate = startDate,
                EndDate = endDate,
                Records = stockInRecords.Concat(stockOutRecords).ToList()
            };
        }
        //统计按钮 统计仓库 商品 总金额
        //还有统计按钮能不能在前端实现

        //计算当天的进出库的总额度

        public async Task<DailyStockSummaryDto> GetDailyStockSummaryAsync(DateTime date)
        {
            // 查询当天的入库记录
            var stockInRecords = await _stockInDetailRepository
                .GetAll()
                .Join(
                    _stockInOrderRepository.GetAll(),
                    detail => detail.OrderID,            // StockInDetail 的外键 OrderID
                    order => order.OrderID,              // StockInOrder 的主键 OrderID
                    (detail, order) => new
                    {
                        detail.Quantity,
                        detail.PurchasePrice,
                        OrderDate = order.OrderDate       // 从 StockInOrder 获取 OrderDate
                    }
                )
                .Where(record => record.OrderDate.Date == date.Date) // 过滤当天的记录
                .ToListAsync();

            // 查询当天的出库记录
            var stockOutRecords = await _stockOutDetailRepository
                .GetAll()
                .Join(
                    _stockOutOrderRepository.GetAll(),
                    detail => detail.OrderID,            // StockOutDetail 的外键 OrderID
                    order => order.OrderID,              // StockOutOrder 的主键 OrderID
                    (detail, order) => new
                    {
                        detail.Quantity,
                        detail.SalePrice,
                        OrderDate = order.OrderDate       // 从 StockOutOrder 获取 OrderDate
                    }
                )
                .Where(record => record.OrderDate.Date == date.Date) // 过滤当天的记录
                .ToListAsync();

            // 计算总额度
            var totalStockInAmount = stockInRecords.Sum(x => x.Quantity * x.PurchasePrice);
            var totalStockOutAmount = stockOutRecords.Sum(x => x.Quantity * x.SalePrice);

            return new DailyStockSummaryDto
            {
                Date = date,
                TotalStockInAmount = totalStockInAmount,
                TotalStockOutAmount = totalStockOutAmount
            };
        }


    }
}
